package ar.com.seminario.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ar.com.seminario.common.persistence.dao.GenericDao;
import ar.com.seminario.common.persistence.exception.DaoException;
import ar.com.seminario.common.service.definition.BaseService;
import ar.com.seminario.common.service.exception.ServiceException;
import ar.com.seminario.dao.CandidatoDao;
import ar.com.seminario.dto.CandidatoDto;
import ar.com.seminario.dto.PerfilDto;
import ar.com.seminario.dto.PropuestaIngresoDto;
import ar.com.seminario.model.Candidato;
import ar.com.seminario.model.Perfil;
import ar.com.seminario.model.PropuestaIngreso;
import ar.com.seminario.model.SolicitudIngreso;

/**
 * Servicio de acceso a los candidatos.
 * 
 * @author Dario Camarro
 * @author Pablo Lamas
 * 
 */
@Service
@Transactional
public class CandidatoService extends BaseService implements ICandidatoService {

	/**
	 * Servicio de acceso a {@link PropuestaIngreso}
	 */
	@Autowired
	private IPropuestaIngresoService propuestaIngresoService;

	/**
	 * Servicio de acceso a {@link Perfil}
	 */
	@Autowired
	private IPerfilService perfilService;

	/**
	 * Servicio de acceso a {@link SolicitudIngreso}
	 */
	@Autowired
	private ISolicitudIngresoService solicitudIngresoService;

	/**
	 * Servicio de acceso a {@link SolicitudCanditato}
	 */
	@Autowired
	private ISolicitudCandidatoService solicitudCandidatoService;

	public List<CandidatoDto> getCandidatosDtoPorNombre(String nombre) {
		List<CandidatoDto> candidatos = null;
		try {
			CandidatoDao sdao = this.getDaoFactory().newDao(CandidatoDao.class);

			List<Candidato> solicitudes = sdao.getAll(Candidato.class);

			candidatos = this.getLisDTO(solicitudes);

		} catch (DaoException e) {

			e.printStackTrace();
		}

		return candidatos;
	}

	public List<CandidatoDto> getAllCandidatosDto() throws ServiceException {
		try {

			final GenericDao<Candidato, Long> dao = this.getDaoFactory()
					.newDao();
			return this.getLisDTO(dao.getAll(Candidato.class));

		} catch (Exception e) {
			throw new ServiceException(e);
		}
	}

	public CandidatoDto getCandidatoDto(Candidato candidato) {

		List<PropuestaIngresoDto> propuestas = new ArrayList<PropuestaIngresoDto>();
		if (candidato.getAllPropuestasIngreso() != null) {
			for (PropuestaIngreso propuestaIngreso : candidato
					.getAllPropuestasIngreso()) {
				propuestas.add(this.propuestaIngresoService
						.getPropuestaIngresoDto(propuestaIngreso));
			}
		}

		PerfilDto perfilDto = new PerfilDto();
		if (candidato.getPerfil() != null) {
			perfilDto = this.perfilService.getPerfilDto(candidato.getPerfil());
		}

		SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");

		return new CandidatoDto(candidato.getId(), candidato.getApellido(),
				candidato.getNombre(), sdf.format(candidato
						.getFechaNacimiento()), candidato.getDireccion(),
				candidato.getRemuneracionPretendida(),
				candidato.getPresentacionGeneral(),
				candidato.getExpresionVerbal(),
				candidato.getMotivoParaCambio(),
				candidato.getCondicionesLaboralActual(),
				candidato.getDisponibilidadIngreso(),
				candidato.getDisponibilidadParaViajar(), propuestas, perfilDto);
	}

	public CandidatoDto getCandidatoDtoPorId(Long idCandidato) {

		try {
			CandidatoDao cdao = this.getDaoFactory().newDao(CandidatoDao.class);
			return this.getCandidatoDto(cdao.getCandidatoPorId(idCandidato));
		} catch (DaoException e) {
			e.printStackTrace();
		}
		return null;
	}

	private List<CandidatoDto> getLisDTO(List<Candidato> candidatos) {

		List<CandidatoDto> candidatosDTO = null;
		if (!candidatos.isEmpty()) {
			candidatosDTO = new Vector<CandidatoDto>();
			for (Candidato Candidato : candidatos) {
				CandidatoDto solicitudDto = this.getCandidatoDto(Candidato);
				candidatosDTO.add(solicitudDto);
			}
		}

		return candidatosDTO;
	}

	public void saveCandidato(CandidatoDto candidatoNuevo)
			throws ServiceException {

		try {

			CandidatoDao dao = this.getDaoFactory().newDao(CandidatoDao.class);
			Candidato nuevoCandidato;
			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

			// Si el id es != null hay que editar y no crear un candidato.
			if (candidatoNuevo.getId() != null) {
				nuevoCandidato = dao.getCandidatoPorId(candidatoNuevo.getId());
			} else {
				nuevoCandidato = new Candidato();
			}

			nuevoCandidato.setApellido(candidatoNuevo.getApellido());
			nuevoCandidato.setCondicionesLaboralActual(candidatoNuevo
					.getCondicionesLaboralActual());
			nuevoCandidato.setDireccion(candidatoNuevo.getDireccion());
			nuevoCandidato.setDisponibilidadIngreso(candidatoNuevo
					.getDisponibilidadIngreso());
			nuevoCandidato.setDisponibilidadParaViajar(candidatoNuevo
					.getDisponibilidadParaViajar());
			nuevoCandidato.setExpresionVerbal(candidatoNuevo
					.getExpresionVerbal());
			nuevoCandidato.setFechaNacimiento(sdf.parse(candidatoNuevo
					.getFechaNacimiento()));
			nuevoCandidato.setMotivoParaCambio(candidatoNuevo
					.getMotivoParaCambio());
			nuevoCandidato.setNombre(candidatoNuevo.getNombre());
			nuevoCandidato.setPresentacionGeneral(candidatoNuevo
					.getPresentacionGeneral());
			nuevoCandidato.setRemuneracionPretendida(candidatoNuevo
					.getRemuneracionPretendida());

			// El perfil del candidato se carga en las entrevistas.
			nuevoCandidato.setPerfil(null);

			dao.saveOrUpdate(nuevoCandidato);

		} catch (Exception e) {
			throw new ServiceException(e);
		}

	}

	public void asociarPostulanteNuevo(CandidatoDto candidatoNuevo)
			throws ServiceException {

		try {

			SolicitudIngreso solicitudIngreso = this.solicitudIngresoService
					.getSolicitudPorId(candidatoNuevo.getIdSolicitudIngreso());

			if (solicitudIngreso != null) {

				Candidato nuevoCandidato = new Candidato();
				SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

				nuevoCandidato.setApellido(candidatoNuevo.getApellido());
				nuevoCandidato.setCondicionesLaboralActual(candidatoNuevo
						.getCondicionesLaboralActual());
				nuevoCandidato.setDireccion(candidatoNuevo.getDireccion());
				nuevoCandidato.setDisponibilidadIngreso(candidatoNuevo
						.getDisponibilidadIngreso());
				nuevoCandidato.setDisponibilidadParaViajar(candidatoNuevo
						.getDisponibilidadParaViajar());
				nuevoCandidato.setExpresionVerbal(candidatoNuevo
						.getExpresionVerbal());
				nuevoCandidato.setFechaNacimiento(sdf.parse(candidatoNuevo
						.getFechaNacimiento()));
				nuevoCandidato.setMotivoParaCambio(candidatoNuevo
						.getMotivoParaCambio());
				nuevoCandidato.setNombre(candidatoNuevo.getNombre());
				nuevoCandidato.setPresentacionGeneral(candidatoNuevo
						.getPresentacionGeneral());
				nuevoCandidato.setRemuneracionPretendida(candidatoNuevo
						.getRemuneracionPretendida());

				// El perfil del candidato se carga en las entrevistas.
				nuevoCandidato.setPerfil(null);

				// Se guarda el candidato.
				CandidatoDao dao = this.getDaoFactory().newDao(
						CandidatoDao.class);
				dao.saveOrUpdate(nuevoCandidato);

				// Se lo asocia a la solicitud de ingreso.
				this.solicitudCandidatoService.saveSolicitudCandidato(
						solicitudIngreso, nuevoCandidato);

			}

		} catch (Exception e) {
			throw new ServiceException(e);
		}

	}

	public Candidato getCandidatoPorId(Long idCandidato)
			throws ServiceException {

		try {

			CandidatoDao cdao = this.getDaoFactory().newDao(CandidatoDao.class);
			return cdao.getCandidatoPorId(idCandidato);

		} catch (DaoException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<CandidatoDto> getCandidatosPorPerfiles(
			List<PerfilDto> perfilesCompatibles) {
		List<CandidatoDto> postulantes = new Vector<CandidatoDto>();
		try {
			CandidatoDao dao = this.getDaoFactory().newDao(CandidatoDao.class);
			for (PerfilDto perfilDto : perfilesCompatibles) {
				Candidato candidato = dao.getCandidatoPorPerfil(perfilService.getPerfilById(perfilDto.getId()));
				if (candidato != null) {
					postulantes.add(getCandidatoDto(candidato));
				}
			}

			return postulantes;
		} catch (DaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}

}
